#include "io_service_pool.h"

io_service_pool::io_service_pool(): m_next_io_service(0)
{}

io_service_pool::~io_service_pool()
{}

void io_service_pool::init(std::size_t pool_size)
{
    if (pool_size == 0)
        throw std::runtime_error("io_service_pool size is 0");

    m_pool_size = pool_size;
    for (std::size_t i = 0; i < m_pool_size; ++i)
    {
        io_service_ptr p_io_service(new boost::asio::io_service() );
		work_ptr work(new boost::asio::io_service::work(*p_io_service));
        m_io_services.push_back(p_io_service);
        m_works.push_back(work);

		boost::shared_ptr<boost::thread> do_async(new boost::thread(boost::bind(&boost::asio::io_service::run, p_io_service)));
		m_io_threads.push_back(do_async);
    }
}

void io_service_pool::wait_for_stop()
{
    for (std::size_t i = 0; i < m_io_services.size(); ++i)
    {   
        m_io_services[i]->stop();
    }

    for (std::size_t i = 0; i < m_io_threads.size(); ++i)
    {
        m_io_threads[i]->join();
    }
}

boost::shared_ptr<boost::asio::io_service> io_service_pool::get_io_service()
{
	io_service_ptr io_service_ref = m_io_services[m_next_io_service];
    ++m_next_io_service;

    if (m_next_io_service == m_io_services.size())
        m_next_io_service = 0;
    return io_service_ref;
}
